import fs from 'fs'
import path from 'path'
import { nanoid } from 'nanoid'

/**
 * 解析路径为绝对路径
 * @param root 根路径
 * @param _path 路径
 */
export function resolvePath(root: string, _path: string) {
  if (path.isAbsolute(_path)) {
    return _path
  } else {
    return path.join(root, _path)
  }
}

/**
 * 返回指定目录随机的文件路径
 * @param root 根路径
 * @param ext 文件后缀名
 * @param len 随机文件名长度
 */
export function randomNamePath(root: string, ext?: string, len?: number) {
  const _ext = ext ? '.' + ext : ''
  let _path: string
  let name: string

  do {
    name = nanoid(len) + _ext
    _path = path.join(root, name)
  } while (fs.existsSync(_path))

  return [_path, name]
}

/**
 * 判断是否为子路径
 * @param parentPath 父路径
 * @param childPath 子路径
 * @param notSame 相同的路径时否返回 false
 */
export function isSubPath(parentPath: string, childPath: string, notSame = true) {
  const relativePath = path.relative(parentPath, childPath)
  if (notSame && relativePath === '') return false
  return !relativePath.startsWith('..') && !path.isAbsolute(relativePath)
}

/**
 * 判断两个路径是否指向同一位置
 * @param path1 路径1
 * @param path2 路径2
 * @param p 是否在路径格式（相对路径、绝对路径）不一致返回 false
 * @param root 根路径
 */
export function arePathsEqual(path1: string, path2: string, p = true, root?: string) {
  // 格式不一致时返回 false
  if (p && path.isAbsolute(path1) !== path.isAbsolute(path2)) {
    return false
  }

  const paths1 = [path1]
  const paths2 = [path2]

  if (root && !path.isAbsolute(path1)) {
    paths1.unshift(root)
  }
  if (root && !path.isAbsolute(path2)) {
    paths2.unshift(root)
  }

  const p1 = path.resolve(...paths1)
  const p2 = path.resolve(...paths2)

  return p1 === p2
}

/**
 * 检查路径
 * @param _path 路径
 * @param type 类型
 */
export function checkPath(_path: string, type: 'file' | 'dir') {
  const res: CheckPathResult = {
    exist: fs.existsSync(_path),
    typeError: false
  }

  if (res.exist) {
    const stat = fs.statSync(_path)

    res.typeError = type === 'file' ? !stat.isFile() : !stat.isDirectory()
  }

  return res
}

type CheckPathResult = {
  exist: boolean
  typeError: boolean
}

export type SortOrder = 'asc' | 'desc'

export function sortPaths(paths: string[], order: SortOrder = 'desc'): string[] {
  return paths.sort((a, b) => {
    const aParts = path.normalize(a).split(path.sep)
    const bParts = path.normalize(b).split(path.sep)

    for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
      if (aParts[i] !== bParts[i]) {
        return aParts[i] < bParts[i] ? -1 : 1
      }
    }

    if (order === 'asc') {
      return aParts.length - bParts.length
    } else {
      return bParts.length - aParts.length
    }
  })
}
